﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Input;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using VMDS.Business.Entities;
using VMDS.Business.Processes;
using VMDS.GUIClient.Helper;
using VMDS.GUIClient.Model;

namespace VMDS.GUIClient.ViewModels.Management.VMs
{
    class AddVmViewModel:BaseViewModel
    {
        private string _name;
        public string VmName
        {
            get { return _name; }
            set { _name = value;
                OnPropertyChanged(() => VmName);
                OnPropertyChanged(() => GoToStep2);
                canGoto2();

            }
        }

        private ObservableCollection<ScreenShot> _screens= new ObservableCollection<ScreenShot>()
                         {
                         };
        public ObservableCollection<ScreenShot> ScreenShots
        {
            get { return _screens; }
            set { _screens = value;OnPropertyChanged(()=>ScreenShots); }
        }

        private ScreenShot _scr;
        public ScreenShot CurrentScreen
        {
            get { return _scr; }
            set { _scr = value;OnPropertyChanged(()=>CurrentScreen);
                OnPropertyChanged(() => DeleteCurrentScr);
            }
        }

        private string _desc;

        public string Description
        {   
            get { return _desc; }
            set { _desc = value;
                OnPropertyChanged(() => Description);
            }
        }

        private string _path;
        public string LocalPath
        {
            get { return _path; }
            set { _path = value;OnPropertyChanged(()=>LocalPath);
                OnPropertyChanged(()=>GoToStep2);
            }
        }

        private string _msg;
        public string ValidMsg
        {
            get { return _msg; }
            set { _msg = value;OnPropertyChanged(()=>ValidMsg); }
        }

        
        private bool _zip;
        public bool IsZip
        {
            get { return _zip; }
            set { _zip = value;
                OnPropertyChanged(() => IsZip);
                OnPropertyChanged(() => IsVmx);
            }
        }
        
        public bool IsVmx
        {
            get { return !_zip; }
            set
            {
                _zip = !value;
                OnPropertyChanged(() => IsZip);
                OnPropertyChanged(() => IsVmx);
            }
        }

        private string _scrpath;
        public string ScreenPath
        {
            get { return _scrpath; }
            set
            {
                _scrpath = value; OnPropertyChanged(() => ScreenPath);
                OnPropertyChanged(() => AddScreen);
            }
        }

        public ICommand AddScreen
        {
            get
            {
                return new BaseCommand(
                    () =>
                        {
                            ScreenShots.Add(new ScreenShot() {FileName = ScreenPath});
                        },
                        () => { return File.Exists(ScreenPath); }
                        
                    );
            }
        }

        private string _logo;
        public string Logo
        {
            get { return _logo; }
            set { _logo = value;OnPropertyChanged(()=>Logo); }
        }
        public ICommand AddLogo
        {
            get
            {
                return new BaseCommand(
                    () =>
                    {
                        ScreenShots.Add(new ScreenShot() { FileName = ScreenPath });
                    },
                        () => { return File.Exists(ScreenPath); }

                    );
            }
        }

        public ICommand DeleteCurrentScr
        {
            get
            {
                return new BaseCommand(
                    () =>
                    {
                        ScreenShots.Remove(CurrentScreen);
                    },
                        () => { return CurrentScreen != null; }
                    );
            }
        }


        public ICommand GoToStep1
        {
            get { return new BaseCommand(() => step(1)); }
        }
        public ICommand GoToStep2
        {
            get { return new BaseCommand(() => step(2),canGoto2); }
        }

        public ICommand GoToStep3
        {
            get { return new BaseCommand(() => step(3)); }
        }
        public ICommand GoToStep4
        {
            get { return new BaseCommand(() => step(4)); }
        }
        public ICommand Cancel
        {
            get { return new BaseCommand(cancelSetup); }
        }

        private string _cs;
        public string CancelStr
        {
            get { return _cs; }
            set { _cs = value;
                OnPropertyChanged(() => CancelStr);
            }
        }

        void cancelSetup()
        {
            if (t != null) t.Abort();
            uploader = null;
            var page = CrossWindowConnector.Pages.VmWizard;
            ((VmNavigationModel)CrossWindowConnector.VmAdmNavigation).NavigationLink = page;
        }

        private int _op;
        public int OperationProgress
        {
            get { return _op; }
            set { _op = value;
                OnPropertyChanged(() => OperationProgress);
            }
        }

        private string _opmsg;
        public string OperationMessage
        {
            get { return _opmsg; }
            set { _opmsg = value;
                OnPropertyChanged(()=>OperationMessage);
            }
        }
 
        bool canGoto2()
        {
            var c1 = String.IsNullOrWhiteSpace(VmName);
            var denied = "><|*?/\\:\"";
            var c0 =false;
            if (!c1) c0 = VmName.Any(c => denied.Contains(c));
            bool c2=false;
            if (!c1)  c2 = ManagerDataStore.Instance.VMs.Any(x => x.Name.ToLower() == VmName.ToLower());
            if (c1||c2||c0)
            {
                ValidMsg = "Введите корректное имя";
                return false;
            }
            if (!File.Exists(LocalPath))
            {
                ValidMsg = "Укажите путь к файлу";
                return false;
            }
            ValidMsg = "";
            return true;
        }
       
        void step(int n)
        {
            string page="";
            switch (n)
            {
                case 1:
                    page = CrossWindowConnector.Pages.AddVmStep1;
                    break;

                case 2:
                    page = CrossWindowConnector.Pages.AddVmStep2;
                    break;

                case 3:
                    page = CrossWindowConnector.Pages.AddVmStep3;
                    break;
                case 4:
                    {
                        page = CrossWindowConnector.Pages.AddVmStep4;
                        Adding();
                        break;
                    }
                    

            }
            ((VmNavigationModel)CrossWindowConnector.VmAdmNavigation).NavigationLink = page;
        }

        private BackgroundWorker uploader;
        void Adding()
        {
            uploader = new BackgroundWorker();
            uploader.DoWork += new DoWorkEventHandler(uploader_DoWork);
            uploader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(uploader_RunWorkerCompleted);
            uploader.RunWorkerAsync();
           
        }

        
        void uploader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            
        }

        private int code;

        private Thread t;
        void uploader_DoWork(object sender, DoWorkEventArgs e)
        {
            bool success = true;
            var Share = ServiceLocator.MainService.GetShareUNC();
                if (!Directory.Exists(Share))
                {
                    OperationMessage = Share + " недоступно";
                    success = false;
                }
            CancelStr = "Отмена";
            t = Thread.CurrentThread;
            Deployer d = new Deployer()
                             {
                                 SubDirectory = "VM",
                                 TargetName = VmName,
                                 LocalPath = LocalPath,
                                 CacheDirectory = "d:\\virtual\\cache"
                             };
            d.PropertyChanged += new PropertyChangedEventHandler(d_PropertyChanged);
            if (success)
            {
                try
                {
                    d.Start();
                }
                catch
                {
                    OperationMessage = "Ошибка загрузки";
                    success = false;
                }
            }

            var vm = new VM()
                         {
                             Name = VmName,
                             Description = Description
                         };
            FileCopier copier = new FileCopier();
            copier.CopyProgress += new CopyProgressEventHandler(copier_CopyProgress);
            if (success)
            {
                if (File.Exists(Logo))
                    try
                    {
                        var fn = new FileInfo(Logo);
                        OperationMessage = "Добавление " + fn.Name;
                        var ext = fn.Extension;
                        copier.CopyFile(Logo, Share + "\\VM\\" + VmName + "\\" + "icon" + ext);
                    }
                    catch
                    {
                        OperationMessage = "Ошибка копирования";
                        success = false;
                    }
            }
            if (success)
            {
                foreach (var scr in ScreenShots)
                {
                    try
                    {
                        var fn = new FileInfo(scr.FileName).Name;
                        OperationMessage = "Добавление " + fn;
                        copier.CopyFile(scr.FileName, Share + "\\VM\\" + VmName + "\\" + fn);
                    }
                    catch
                    {
                        OperationMessage = "Ошибка загрузки изображений";
                        success = false;
                    }
                }
            }
            if (success)
            {
                try
                {
                    ServiceLocator.MainService.AddVm(vm);
                    OperationMessage = "Виртуальная машина добавлена";
                    CancelStr = "Готово";
                }
                catch
                {
                    OperationMessage = "Ошибка регистрации";
                }
                ManagerDataStore.Instance.LoadData();
            }
            
          
        }

        void copier_CopyProgress(object sender, CopyProgressEventArgs e)
        {
            OperationProgress = (int)(e.TotalBytesTransferred * 100 / e.TotalFileSize);
        }

        void d_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "OperMessage") OperationMessage = ((Deployer)sender).OperMessage;
            if (e.PropertyName == "OperProgress") OperationProgress = ((Deployer)sender).OperProgress;
        }
        


        static AddVmViewModel _inst;
        public static AddVmViewModel Instance
        {
            get { return _inst ?? (_inst = new AddVmViewModel()); }
        }
        
        public void ReInit()
        {
            _inst = new AddVmViewModel();
        }
        
    }
}
